package com.quik.web.front.action;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.quik.common.Constants;
import com.quik.dto.OpenTokenDto;
import com.quik.dto.PaginationDto;
import com.quik.entity.BillingItem;
import com.quik.entity.BizBilling;
import com.quik.entity.BizBillingItem;
import com.quik.entity.BizBillingRelatedItem;
import com.quik.entity.DtaProduct;
import com.quik.entity.DtaProductCategory;
import com.quik.entity.DtaProductSubCategory;
import com.quik.entity.Statistics;
import com.quik.entity.SysAccount;
import com.quik.entity.SysSystemCode;
import com.quik.entity.DtaToken;
import com.quik.entity.DtaTokenType;
import com.quik.entity.DtaWorker;
import com.quik.entity.DtaWorkerType;
import com.quik.exception.ErrorCode;
import com.quik.web.front.service.ConsultBillingService;
import com.quik.web.front.service.ConsultTokenService;
import com.quik.web.product.service.ProductService;
import com.quik.web.worker.service.WorkerService;

/**
 * 功能说明： 处理手牌的业务逻辑
 * 
 * @author Jenny
 * 
 */
@Controller
@RequestMapping("/consultToken")
@SuppressWarnings("unchecked")
public class ConsultantTokenController {
	private static Logger log = (Logger) Logger
			.getLogger(ConsultantTokenController.class);

	@Autowired
	private ConsultTokenService consultTokenService;

	@Autowired
	private ConsultBillingService consultBillingService;

	@Autowired
	private ProductService productService;

	@Autowired
	private WorkerService workerService;
	
	@RequestMapping(value = "queryBillingByTokenNo", method = RequestMethod.POST)
	@ResponseBody
	public Object queryBillingByTokenNo(String tokenNo) throws Exception {
		Map<String, Object> data = new  HashMap<String, Object>();
		if (!StringUtils.isEmpty(tokenNo)) {
			BizBilling billing = this.consultBillingService.findBillingByToken(tokenNo);
			data.put("billing", billing);
			List<BizBillingItem> billingItems = this.consultBillingService.findBillingItemByBillingId(billing.getId().toString());
			data.put("billingItems", billingItems);
		}
		Map<String, Object> rs = new  HashMap<String, Object>();
		rs.put("state", "success");
		rs.put("data", data);
		return rs;
	}

	/**
	 * 手牌列表 (显示手牌号、类型、状态)
	 * 
	 * @return
	 */
	@RequestMapping(value = "tokenList", method = RequestMethod.GET)
	public ModelAndView tokenList(String billingId) {
		ModelAndView mav = new ModelAndView("/front/consult/token/tokenList");

		try {
			List<DtaToken> tokenList = consultTokenService.findTokenList(null,
					null);
			List<DtaTokenType> tokenTypeList = consultTokenService
					.findTokenTypeList();
			List<SysSystemCode> tokenStatusList = consultTokenService
					.findTokenStatusList();
			// 统计
			List<Statistics> tokenStatList = consultTokenService
					.findTokenStatList();

			List<DtaProduct> productList = this.productService.findAllProduct();
			List<DtaProductCategory> productCategoryList = this.productService
					.findAllProductCategory();
			List<DtaProductSubCategory> productSubCategoryList = this.productService
					.findAllproductSubCategory();
			if (!StringUtils.isEmpty(billingId)) {
				BizBilling billing = this.consultBillingService.findBillingById(billingId);
				mav.addObject("billing", billing);
				List<BizBillingItem> billingItems = this.consultBillingService.findBillingItemByBillingId(billingId);
				mav.addObject("billingItems", billingItems);
			}

			List<DtaWorkerType> workerTypes = workerService.findWorkerType(null,null,null,null);
			List<DtaWorker> workers = workerService.findAllWorker();
			List<SysSystemCode> callTurns = consultTokenService.findCallTurn();

			mav.addObject("callTurns", callTurns);
			mav.addObject("workers", workers);
			mav.addObject("workerTypes", workerTypes);
			mav.addObject("tokenList", tokenList);
			mav.addObject("tokenTypeList", tokenTypeList);
			mav.addObject("tokenStatusList", tokenStatusList);
			mav.addObject("tokenStatList", tokenStatList);
			mav.addObject("productList", productList);
			mav.addObject("productCategoryList", productCategoryList);
			mav.addObject("productSubCategoryList", productSubCategoryList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenController tokenList error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 根据手牌类型和状态查询手牌列表
	 * 
	 * @param tokenType
	 * @param tokenStatus
	 * @return
	 */
	@RequestMapping(value = "queryTokenList", method = RequestMethod.POST)
	@ResponseBody
	public List queryTokenList(Integer tokenType, String tokenStatus) {
		List tokenList = null;

		try {
			tokenList = consultTokenService
					.findTokenList(tokenType, tokenStatus != null
							&& tokenStatus.trim().length() > 0 ? tokenStatus
							: null);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenController queryTokenList error: "
					+ e.getMessage());
		}

		return tokenList;
	}

	/**
	 * 进入开手牌界面
	 * 
	 * @return
	 */
	@RequestMapping(value = "initOpenToken")
	public ModelAndView initOpenToken(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView("/front/consult/token/openToken");

		try {
			// 查询手牌类型
			List tokenTypeList = consultTokenService.findTokenTypeList();

			String tokenNo = (String) request.getAttribute("tokenNo");
			if (tokenNo != null && tokenNo.length() > 0) {
				mav.addObject("tokenNo", tokenNo);
			}

			mav.addObject("tokenTypeList", tokenTypeList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenContorller initOpenToken error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 手牌详情 手牌空闲时，直接进行开手牌 手牌占用时，直接进入手牌详情
	 * 
	 * @param tokenNo
	 * @param status
	 * @return
	 */
	@RequestMapping(value = "tokenDetail")
	public ModelAndView tokenDetail(String tokenNo, String status) {
		ModelAndView mav = new ModelAndView("/front/consult/token/tokenDetail");

		try {
			if (status.equals(DtaToken.TOKEN_STATUS_FREE)) {// 跳转开手牌
				mav.addObject("tokenNo", tokenNo);
				mav.setViewName("forward:/consultToken/initOpenToken");
			} else if (status.equals(DtaToken.TOKEN_STATUS_USED)) { // 跳转详情界面
				DtaToken token = consultTokenService.getTokenByTokenNo(tokenNo
						.trim());
				// 查询关联帐单
				List billingList = consultBillingService
						.findRelateBillingByItemNo(tokenNo.trim(),
								BizBillingRelatedItem.ITEM_TYPE_TOKEN);
				// 查询关联手牌
				List tokenList = consultBillingService
						.findRelateTokenByBillingId(billingList);
				// 查询关联房间
				List roomList = consultBillingService
						.findRelateRoomByBillingId(billingList);
				// 查询棋牌消费明细
				List chessList = consultBillingService
						.findChessConsumeByBillingId(billingList);
				// 查询服务消费明细
				List serviceList = consultBillingService
						.findServiceConsumeByBillingId(billingList);
				// 查询其它明细
				List otherList = consultBillingService
						.findOtherConsumeByBillingId(billingList);

				mav.addObject("token", token);
				mav.addObject("tokenList", tokenList);
				mav.addObject("roomList", roomList);
				mav.addObject("billingList", billingList);
				mav.addObject("chessList", chessList);
				mav.addObject("serviceList", serviceList);
				mav.addObject("otherList", otherList);
				mav.addObject("IS_ABLE", BizBillingItem.STATUS_YES);
				mav.addObject("IF_MASTER", BizBilling.MASTER_YES);
				mav.addObject("PRODUCT_YES", DtaProduct.OPTION_FOR_YES);
				mav.addObject("PRODUCT_NO", DtaProduct.OPTION_FOR_NO);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenController tokenDetail error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 根据条件查询空闲状态的手牌列表
	 * 
	 * @param page
	 * @param rows
	 * @param tokenNo
	 * @param tokenType
	 * @return
	 */
	@RequestMapping(value = "queryToken", method = RequestMethod.POST)
	@ResponseBody
	public PaginationDto queryToken(Integer page, Integer rows, String tokenNo,
			Integer tokenType) {
		PaginationDto dto = new PaginationDto(0, null);

		try {
			int intPage = (page == null || page == 0) ? 1 : page; // 当前页
			int pageSize = (rows == null || rows == 0) ? Constants.TREE_PAGE_SIZE
					: rows; // 每页显示的记录

			int totalCount = consultTokenService.findTokenCount(tokenNo,
					tokenType, DtaToken.TOKEN_STATUS_FREE);
			List list = consultTokenService.findTokenList(tokenNo, tokenType,
					DtaToken.TOKEN_STATUS_FREE, intPage, pageSize);

			dto.setRows(list);
			dto.setTotal(totalCount);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenContorller queryToken error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 开手牌
	 * 
	 * @param tokenNo
	 * @param contactStaffNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "openToken", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto openToken(String tokenNo, String contactStaffNo,
			HttpServletRequest request) {
		OpenTokenDto dto = new OpenTokenDto();
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			consultTokenService.openToken(tokenNo, contactStaffNo,
					account.getStaff_no());

			// 查询界面展示的对象
			BillingItem item = consultTokenService
					.findBillingItemByTokenNo(tokenNo);

			dto.setResult("success");
			dto.setObj(item);
		} catch (Exception e) {
			throw new RuntimeException("ConsultantTokenContorller openToken error: "
					+ e, e);
		}

		return dto;
	}

	/**
	 * 开手牌
	 * 
	 * @param tokenNo
	 * @param contactStaffNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "openTokens", method = RequestMethod.POST)
	public ModelAndView openTokens(String[] tokenNos, String contactStaffNo,
			HttpServletRequest request) {
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);
		Integer id = 0;
		String tokenNo = null;
		try {
			BizBilling billing = consultTokenService.openTokens(tokenNos,
					contactStaffNo, account.getStaff_no());
			id = billing.getId();
			if(tokenNos!=null&&tokenNos.length>0){
				tokenNo = tokenNos[0];
			}
		} catch (Exception e) {
			throw new RuntimeException(
					"ConsultantTokenContorller openToken error: " + e, e);
		}

		return new ModelAndView("redirect:/consultToken/tokenList?billingId="
				+ id+"&tokenNo="+(tokenNo==null?"":tokenNo));
	}

	/**
	 * 关联开牌
	 * 
	 * @param srcTokenNo
	 * @param billingNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "relateToken", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto relateToken(String tokenNo, String billingNo,
			String contactStaffNo, HttpServletRequest request) {
		OpenTokenDto dto = new OpenTokenDto();
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			consultTokenService.relateToken(tokenNo, billingNo, contactStaffNo,
					account.getStaff_no());

			// 查询
			BillingItem item = consultTokenService
					.findBillingItemByTokenNo(tokenNo);

			dto.setResult("success");
			dto.setObj(item);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenContorller relateToken error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 进入交换手牌
	 * 
	 * @return
	 */
	@RequestMapping(value = "initExchangeToken", method = RequestMethod.GET)
	public String initExchangeToken() {
		return "/front/consult/token/exchangeToken";
	}

	/**
	 * 交换手牌
	 * 
	 * @param srcToken
	 * @param newToken
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "exchangeToken", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> exchangeToken(String srcToken,
			String newToken, HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			if (consultTokenService.isFree(newToken)) {
				consultTokenService.exchangeToken(srcToken, newToken,
						account.getStaff_no());
				result = "success";
			} else
				result = ErrorCode.RESULT_TOKEN_UNFREE;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenController exchangeToken error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 初始化关联手牌
	 * 
	 * @return
	 */
	@RequestMapping(value = "initRelateToken", method = RequestMethod.GET)
	public ModelAndView initRelateToken() {
		ModelAndView mav = new ModelAndView("/front/consult/token/relateToken");

		try {
			// 查询手牌类型
			List tokenTypeList = consultTokenService.findTokenTypeList();

			mav.addObject("tokenTypeList", tokenTypeList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenContorller initOpenToken error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 根据手牌绑定新开手牌
	 * 
	 * @param boundToken
	 * @param relateToken
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "relateByToken", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> relateByToken(String boundToken,
			String[] relateToken, HttpServletRequest request) {
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);
		String result = ErrorCode.SYSTEM_ERROR;

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			boolean isToken = consultTokenService.isToken(boundToken.trim());
			if (isToken) {
				consultTokenService.relateByToken(boundToken, relateToken,
						account.getStaff_no());
				result = "success";
			} else
				result = ErrorCode.CONSULT_OPENROOM_NO_TOKEN;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantTokenController relateByToken error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}
}
